<html>
    <head>
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
        <script src="./resources/webxr-util.js"></script>
    </head>
    <body>
          <canvas id="canvas" width="640" height="480"></canvas>

        <script>
          let canvas = document.getElementById("canvas");
          let gl = canvas.getContext('webgl');
          promise_test(async function() {
            let mock = await navigator.xr.test.simulateDeviceConnection({
              supportedModes: ["immersive-vr"],
              views: TEST_VIEWS,
              viewerOrigin: {position: [0.5, 0.1, 0.1], orientation: [1, 0, 0, 1] }
            });
            let sessionPromise;
            navigator.xr.test.simulateUserActivation(() => {
              sessionPromise = navigator.xr.requestSession("immersive-vr");
            });
            let session = await sessionPromise;
            await session.updateRenderState({"baseLayer": new XRWebGLLayer(session, gl, {})});
            let resolve;

            let frame = await new Promise(resolve => {
              session.requestAnimationFrame((time, frame) => resolve(frame));
            });

            let space = await session.requestReferenceSpace("local");
            let pose = frame.getViewerPose(space);
            assert_matrix_approx_equals(pose.transform.matrix, [1,0,0,0,0,0,1,0,0,-1,0,0,0.5,0.1,0.1,1], 0.001, "head pose matrix");

            for (view of pose.views) {
              assert_matrix_approx_equals(view.projectionMatrix, VALID_PROJECTION_MATRIX, 0.001, "projection matrix");
              if (view.eye == "left") {
                assert_matrix_approx_equals(view.transform.matrix,         [1,0,0,0,0,0,1,0,0,-1,0,0,0.4,0.1,0.1,1], 0.001, "left transform");
                assert_matrix_approx_equals(view.transform.inverse.matrix, [1,0,0,0,0,0,-1,0,0,1,0,0,-0.4,-0.1,0.1,1], 0.001, "left inverse transform");
                let position = view.transform.position;
                assert_approx_equals(position.x, 0.4, 0.001, "left x value");
                assert_approx_equals(position.y, 0.1, 0.001, "left y value");
                assert_approx_equals(position.z, 0.1, 0.001, "left z value");
                assert_approx_equals(position.w, 1, 0.001, "left w value");
              } else if (view.eye == "right") {
                assert_matrix_approx_equals(view.transform.matrix,         [1,0,0,0,0,0,1,0,0,-1,0,0,0.6,0.1,0.1,1], 0.001, "right transform");
                assert_matrix_approx_equals(view.transform.inverse.matrix, [1,0,0,0,0,0,-1,0,0,1,0,0,-0.6,-0.1,0.1,1], 0.001, "right inverse transform");
                let position = view.transform.position;
                assert_approx_equals(position.x, 0.6, 0.001, "left x value");
                assert_approx_equals(position.y, 0.1, 0.001, "left y value");
                assert_approx_equals(position.z, 0.1, 0.001, "left z value");
                assert_approx_equals(position.w, 1, 0.001, "left w value");
              } else {
                throw "got unknown view";
              }
            }
            let offset = space.getOffsetReferenceSpace(new XRRigidTransform({x: 1, y: -1, z: 4}, {x: 0, y: 1, z: 1, w: 1}));
            pose = frame.getViewerPose(offset);
            for (view of pose.views) {
              if (view.eye == "left") {
                assert_matrix_approx_equals(view.transform.matrix, [-1/3,-2/3,2/3,0,-2/3,2/3,1/3,0,-2/3,-1/3,-2/3,0,3.5 + 1/30,-1.9 + 2/30,-0.9 - 2/30,1], 0.001, "left offset transform");
              } else if (view.eye == "right") {
                assert_matrix_approx_equals(view.transform.matrix, [-1/3,-2/3,2/3,0,-2/3,2/3,1/3,0,-2/3,-1/3,-2/3,0,3.5 - 1/30,-1.9 - 2/30,-0.9 + 2/30,1], 0.001, "right offset transform");
              } else {
                throw "got unknown view";
              }
            }
            let viewer = await session.requestReferenceSpace("viewer");
            pose = frame.getViewerPose(viewer);
            assert_matrix_approx_equals(pose.transform.matrix, [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1], 0.001, "viewerPose of viewer is identity");
            assert_matrix_approx_equals(frame.getViewerPose(space).transform.matrix, frame.getPose(viewer, space).transform.matrix, 0.001, "viewerPose(space) == pose(viewer, space)");
            assert_matrix_approx_equals(frame.getViewerPose(offset).transform.matrix, frame.getPose(viewer, offset).transform.matrix, 0.001, "viewerPose(offset) == pose(viewer, offset)");

          });
        </script>
    </body>
</html>
